/**
 *    @file       perlregexp.h
 *
 *    @brief      
 *    @details    refer to http://www.pcre.org/pcre.txt
 *				  http://blog.csdn.net/sulliy/article/details/6247155
 *
 *    @version    1.0
 *    @date       01/26/2014 12:48:35 AM
 *
 *    @author     Theophilus (), wangtf418@gmail.com 
 */
#ifndef _BF_PERLREGEXP_H_
#define _BF_PERLREGEXP_H_

#ifndef __WITHOUT_PCRE__
#include <pcre.h>
#include<vector>
#include "comdef.h"

class perlregexp
{
public:
	perlregexp();
	~perlregexp();

public:
	 ///option : PCRE_ANCHORED, PCRE_AUTO_CALLOUT, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE, PCRE_CASELESS ...
	bf_int_t compile(const bf_char_t *pattern, bf_int_t option = 0);
	///option : PCRE_ANCHORED, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE, PCRE_NEWLINE_CR, PCRE_NEWLINE_LF ...
	bf_int_t execute(const bf_char_t *str, bf_int_t strlen, bf_uint_t max_groupno = 10, bf_int_t option = 0, bf_int_t startpos = 0);

public:
	inline const std::string & get_errmsg()
	{
		return m_errmsg;
	}

	inline bf_int_t get_errno()
	{
		return m_errno;
	}

	inline bf_int_t get_errpos()
	{
		return m_errpos;
	}

	inline bf_size_t get_matchno()
	{
		return m_match.size() / 3;
	}

	inline const std::vector<bf_int_t> & get_match()
	{
		return m_match;
	}

	inline std::string get_match(const bf_char_t *str, bf_size_t index)
	{
		if (!str || (index * 3) >= m_match.size()) return "";
		bf_int_t pos = 2 * index;
		bf_int_t len = m_match[pos + 1] - m_match[pos];
		if (len <= 0)
		{
			return "";
		}
		return std::string(str + m_match[pos], len);
	}

private:
	std::string m_errmsg;
	bf_int_t m_errno;
	bf_int_t m_errpos;
	pcre *m_pcre_pattern;
	std::vector<bf_int_t> m_match;
};

#endif //end ifndef __WITHOUT_PCRE__

#endif

